/* RadioAssociation.m
 *
 * You may freely copy, distribute, and reuse the code in this example.
 * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
 * fitness for any particular use.
 *
 *  
 *
 */
 
#import <appkit/appkit.h>
#import <eointerface/eointerface.h>

#import "RadioAssociation.h"
 
// Add a category to ButtonCell class to recognize the RadioAssociation
// for Radio Buttons.

@implementation ButtonCell (RadioAssociation)
- (Class)matrixAssociationClass:matrix
{
    const char *iconname;

    if (([matrix mode] == NX_RADIOMODE)
            && (iconname = [self icon])
            && !strcmp(iconname, "NXradio"))
        return [RadioAssociation class];
    else
        return [EOMatrixAssociation class];
}
@end


// Override the standard matrix associationClass method to spot radio
// associations

@implementation Matrix (RadioAssoc)
- (Class)associationClass
{
    id acell;

    //  Determine if we're a matrix of radio buttons!
    acell = [self cellAt:0:0];
    if (acell && [acell respondsToSelector:@selector(matrixAssociationClass:)])
        return [acell matrixAssociationClass:self];
    
    // Use the generic association 
    return [EOMatrixAssociation class];
}

@end


@implementation RadioAssociation

- initWithController:(EOController *)aController
	key: (NSString *)aKey destination: aDest
{
    [super initWithController:aController key: aKey destination:aDest];

    // This is needed to get rid of warning about multiple declarations. 
    [(Matrix *)aDest setTarget:self];
    [aDest setAction:@selector(controlActed:)];

    // Allow empty selection for instances when the EO value doesn't
    // match any of the values
	
    [aDest setEmptySelectionEnabled:YES]; 
    return self;
}

- controlActed:sender
{
    [controller associationDidEdit: self];
    return self;
}


// Return the selected cell string, or NULL if no cell is selected

- value
{
	const char *title = [[destination selectedCell] title];
	if (title) 
		return [NSString stringWithCString:title];
 	 else  
		return [EONull null];

}

- (NSString *)currentValue
{
    NSArray *selectedObjects = [controller selectedObjects];
    NSString *stringValue;
    
    if ([selectedObjects count] >= 1) {
        id selectedObject, aDict, val;
		id array = [[[NSArray alloc] initWithObjects: key, 0] autorelease];
	
		selectedObject = [selectedObjects objectAtIndex: 0];
		aDict = [selectedObject valuesForKeys: array];
		val = [aDict objectForKey: key];
		if (!val)
	   	 	stringValue = @"";
		else
            stringValue = [((NSObject *)val) description];      
	} else {
		stringValue = @"";
    }

    return stringValue;
}

- (void)selectionDidChange
{
    [self contentsDidChange];
}

//
// If no cell matches title, then an empty selection is set
//
- (void)selectCellWithTitle:(NSString *)title
  {
    int col,row,numrows,numcols;
    const char *titleCString = [title cString];

    [destination getNumRows:&numrows numCols:&numcols];
    for(col=0; col<numcols;col++) {
        for(row=0; row<numrows; row++) {
	    id cell = [destination cellAt:row :col];
	    if (cell && !strcmp([cell title], titleCString)) {
	        [destination selectCellAt:row :col];
		return;
	    }
	}
    }
    
	// Clear the selection if no matching cell is found.
    [destination selectCellAt:-1 :-1];
}

- (void)contentsDidChange
{
    [self selectCellWithTitle:[self currentValue]];

    // If there's not exactly one object selected, disable the control
	
    if ([[controller selectedObjects] count] == 1)
        [destination setEnabled:YES];
    else
        [destination setEnabled:NO];
}

@end


